#include "stdafx.h"
#include "ui_gdiplus_render_util.h"


_SSL_BEGIN
_SSUIL_BEGIN


void UIGdiplusRenderUtil::DrawImage(HDC dc, Gdiplus::Image *img, const UIPoint &dst_pt, float rotate /*= 0*/, unsigned int alpha_value /*= 0xff*/)
{
	if(::GetObjectType(dc) != OBJ_DC && ::GetObjectType(dc) != OBJ_MEMDC)
		return;
	if(img == NULL)
		return;
	if(img->GetWidth() == 0 || img->GetHeight() == 0)
		return;

	Gdiplus::Graphics graphics(dc);

	int x = dst_pt.x, y = dst_pt.y;

	Gdiplus::REAL translate_x = 0, translate_y = 0;
	if(rotate != 0)
	{
		translate_x = x + img->GetWidth() / Gdiplus::REAL(2.0);
		translate_y = y + img->GetHeight() / Gdiplus::REAL(2.0);

		graphics.TranslateTransform(translate_x, translate_y);
		graphics.RotateTransform((Gdiplus::REAL)rotate);
		x -= int(translate_x);
		y -= int(translate_y);
		graphics.DrawImage(img, x, y);
		graphics.ResetTransform();
	} else
	{
		graphics.DrawImage(img, x, y);
	}
}

void UIGdiplusRenderUtil::DrawImage(HDC dc, Gdiplus::Image *img, const UIRect *src_rt,
	const UIRect &dest_rt, DWORD mask /*= 0*/, float rotate /*= 0*/, unsigned int alpha_value /*= 0xff*/)
{
	if(::GetObjectType(dc) != OBJ_DC && ::GetObjectType(dc) != OBJ_MEMDC)
		return;
	if(img == NULL)
		return;
	if(img->GetWidth() == 0 || img->GetHeight() == 0)
		return;

	Gdiplus::Graphics graphics(dc);

	Gdiplus::REAL translate_x = 0, translate_y = 0;
	if(rotate != 0)
	{
		translate_x = dest_rt.left + (dest_rt.right - dest_rt.left) / Gdiplus::REAL(2.0);
		translate_y = dest_rt.top + (dest_rt.bottom - dest_rt.top) / Gdiplus::REAL(2.0);
		graphics.TranslateTransform(translate_x, translate_y);
		graphics.RotateTransform((Gdiplus::REAL)rotate);
	}

	Gdiplus::ImageAttributes oImgAttris;
	oImgAttris.SetWrapMode(Gdiplus::WrapModeTileFlipXY);

	Gdiplus::ColorMatrix color_matrix;
	memset(&color_matrix, 0, sizeof(color_matrix));
	color_matrix.m[0][0] = 1;
	color_matrix.m[1][1] = 1;
	color_matrix.m[2][2] = 1;
	color_matrix.m[3][3] = alpha_value / 255.0f;
	color_matrix.m[4][4] = 1;
	oImgAttris.SetColorMatrices(&color_matrix, NULL);

	if(mask != 0)
	{
		oImgAttris.SetColorKey(Gdiplus::Color(
			GetRValue(mask), GetGValue(mask), GetBValue(mask)),
			Gdiplus::Color(
			GetRValue(mask), GetGValue(mask), GetBValue(mask)),
			Gdiplus::ColorAdjustTypeBitmap);
	}

	UIRect src_rect;
	if(src_rt != NULL)
	{
		src_rect = *src_rt;
	}else
	{
		src_rect.left = 0;
		src_rect.top = 0;
		src_rect.right = img->GetWidth();
		src_rect.bottom = img->GetHeight();
	}

	Gdiplus::Rect dest_rect;
	dest_rect.X = dest_rt.left;
	dest_rect.Y = dest_rt.top;
	dest_rect.Width = dest_rt.Width();
	dest_rect.Height = dest_rt.Height();
	dest_rect.X -= INT(translate_x);
	dest_rect.Y -= INT(translate_y);
	graphics.DrawImage(img, dest_rect, src_rect.left, src_rect.top,
		src_rect.Width(), src_rect.Height(),
		Gdiplus::UnitPixel, &oImgAttris);

	if(rotate != 0)
	{
		graphics.ResetTransform();
	}
}

void UIGdiplusRenderUtil::Draw9GridImage(HDC dc, Gdiplus::Image *img, const UIRect src_rt[9],
	const UIRect dest_rt[9], WORD mask /*= 0*/, unsigned int alpha_value /*= 0xff*/)
{
	if(::GetObjectType(dc) != OBJ_DC && ::GetObjectType(dc) != OBJ_MEMDC)
		return;
	if(img == NULL)
		return;
	if(img->GetWidth() == 0 || img->GetHeight() == 0)
		return;

	Gdiplus::Graphics graphics(dc);

	Gdiplus::ImageAttributes oImgAttris;
	oImgAttris.SetWrapMode(Gdiplus::WrapModeTileFlipXY);

	Gdiplus::ColorMatrix color_matrix;
	memset(&color_matrix, 0, sizeof(color_matrix));
	color_matrix.m[0][0] = 1;
	color_matrix.m[1][1] = 1;
	color_matrix.m[2][2] = 1;
	color_matrix.m[3][3] = alpha_value / 255.0f;
	color_matrix.m[4][4] = 1;
	oImgAttris.SetColorMatrices(&color_matrix, NULL);

	if(mask != 0)
	{
#pragma warning(push)
#pragma warning(disable:4333)
		oImgAttris.SetColorKey(Gdiplus::Color(
			GetRValue(mask), GetGValue(mask), GetBValue(mask)),
			Gdiplus::Color(
			GetRValue(mask), GetGValue(mask), GetBValue(mask)),
			Gdiplus::ColorAdjustTypeBitmap);
#pragma warning(pop)
	}

	for(int i=0; i<9; i++)
	{
		if(dest_rt[i].Width() <= 0 || dest_rt[i].Height() <= 0)
			continue;

		Gdiplus::Rect dest_rect;
		dest_rect.X = dest_rt[i].left;
		dest_rect.Y = dest_rt[i].top;
		dest_rect.Width = dest_rt[i].Width();
		dest_rect.Height = dest_rt[i].Height();
		graphics.DrawImage(img, dest_rect, src_rt[i].left, src_rt[i].top,
			src_rt[i].Width(), src_rt[i].Height(), Gdiplus::UnitPixel, &oImgAttris);
	}
}

_SSUIL_END
_SSL_END

